#include <basic_types.h>
#include <api/libc/alloc.h>
#include <api/libc/printf.h>
#include <osal/osal.h>

#include <hld/hld_dev.h>
#include <hld/sdec/sdec.h>
#include <hld/sdec/sdec_dev.h>



/*
 * 	Name		:   sdec_open()   	
 *	Description	:   Open a sdec device
 *	Parameter	:	struct sdec_device *dev		: Device to be openned
 *	Return		:	INT32 						: Return value
 *
 */
__ATTRIBUTE_REUSE_
INT32 sdec_open(struct sdec_device *dev)
{
	INT32 result=RET_FAILURE;
	
	/* If openned already, exit */
	if (dev->flags & HLD_DEV_STATS_UP)
	{
		PRINTF("sdec_open: warning - device %s openned already!\n", dev->name);
		return RET_SUCCESS;
	}
	
	/* Open this device */
	if (dev->open)
	{
		result = dev->open(dev);
	}
	
	/* Setup init work mode */
	if (result == RET_SUCCESS)
	{
		dev->flags |= (HLD_DEV_STATS_UP | HLD_DEV_STATS_RUNNING);
		
	}
	
	return result;
}

/*
 * 	Name		:   sdec_close()   	
 *	Description	:   Close a sdec device
 *	Parameter	:	struct sdec_device *dev		: Device to be closed
 *	Return		:	INT32 						: Return value
 *
 */
INT32 sdec_close(struct sdec_device *dev)
{
	INT32 result=RET_FAILURE;

	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		PRINTF("sdec_close: warning - device %s closed already!\n", dev->name);
		return RET_SUCCESS;
	}
	
	/* Stop device */
	if (dev->close)
	{
		result = dev->close(dev);
	}
	
	/* Update flags */
	dev->flags &= ~(HLD_DEV_STATS_UP | HLD_DEV_STATS_RUNNING);
	
	return result;
}
INT32  sdec_start(struct sdec_device *dev,UINT16 composition_page_id,UINT16 ancillary_page_id)
{
	/* If device not running, exit */
	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		return RET_FAILURE;
	}
	
	if (dev->start)
	{
		return dev->start(dev, composition_page_id,ancillary_page_id);
	}
	return RET_FAILURE;
}

INT32  sdec_stop(struct sdec_device *dev)
{
	/* If device not running, exit */
	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		return RET_FAILURE;
	}
	
	if (dev->stop)
	{
		return dev->stop(dev);
	}
	return RET_FAILURE;

}
INT32  sdec_pause(struct sdec_device *dev)
{
	/* If device not running, exit */
	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		return RET_FAILURE;
	}
	
	if (dev->pause)
	{
		return dev->pause(dev);
	}
	return RET_FAILURE;
}
#if 0 //this function be done in lib_subt.c
INT32  sdec_showonoff(struct sdec_device *dev,BOOL bOn)
{
	/* If device not running, exit */
	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		return RET_FAILURE;
	}
	
	if (dev->showonoff)
	{
		return dev->showonoff(dev,bOn);
	}
	return RET_FAILURE;
}
#endif
/*
 * 	Name		:   sdec_io_control()   	
 *	Description	:   sdecel IO control command
 *	Parameter	:	struct sto_device *dev		: Device
 *					INT32 cmd					: IO command
 *					UINT32 param				: Param
 *	Return		:	INT32 						: Result
 *
 */
INT32 sdec_ioctl(struct sdec_device *dev, UINT32 cmd, UINT32 param)
{
	/* If device not running, exit */
	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		return RET_FAILURE;
	}
	
	if (dev->ioctl)
	{
		return dev->ioctl(dev, cmd, param);
	}
	
	return RET_FAILURE;
}

INT32 sdec_request_write(void * pdev, UINT32 uSizeRequested,void ** ppuData,UINT32* puSizeGot,struct control_block* pSDataCtrlBlk)
{
	struct sdec_device *dev = (struct sdec_device *)pdev;	
	/* If device not running, exit */
	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		return RET_FAILURE;
	}
	
	if (dev->request_write)
	{
		return dev->request_write(dev, uSizeRequested, pSDataCtrlBlk,(UINT8 **)ppuData,puSizeGot);
	}
	return RET_FAILURE;
}

void sdec_update_write(void * pdev,UINT32 uDataSize)
{
	struct sdec_device *dev = (struct sdec_device *)pdev;		
	/* If device not running, exit */
	if ((dev->flags & HLD_DEV_STATS_UP) == 0)
	{
		return ;
	}
	
	if (dev->update_write)
	{
		dev->update_write(dev, uDataSize);
	}
}




